package gee

import (
	"net/http"
	"strings"
)

type router struct {
	// method-路由节点树
	roots		map[string]*node
	// key-handlerFunc
	handlers	map[string]HandlerFunc
}

// 新建路由
func newRouter() *router {
	return &router{
		roots: make(map[string]*node),
		handlers: make(map[string]HandlerFunc),
	}
}

// 对pattern做预处理
func parsePattern(pattern string) []string {
	// 以"/"做拆分
	vs := strings.Split(pattern, "/")

	// 依次加入parts切片
	parts := make([]string, 0)
	for _, item := range vs {
		if item != "" {
			parts = append(parts, item)
			// 遇见item中以*开头则停止
			if item[0] == '*' {
				break
			}
		}
	}
	// 返回一个分割好的切片
	return parts
}

// 新增一个路由
func (r *router) addRoute(method string, pattern string, handler HandlerFunc) {
	// 切分pattern，得到parts数组
	parts := parsePattern(pattern)
	// 得到handler函数的key
	key := method + "-" + pattern
	// 有则直接用，没有则创建
	_, ok := r.roots[method]
	if !ok {
		r.roots[method] = &node{}
	}
	// 调用node的insert函数，递归地插入整个路由
	r.roots[method].insert(pattern, parts, 0)
	// 插入handler函数的key-map
	r.handlers[key] = handler
}

// 根据路由得到node节点和params
func (r *router) getRoute(method string, path string) (*node, map[string]string) {
	// 将路径拆分成parts，用作后面搜索的参数
	searchParts := parsePattern(path)
	// params
	params := make(map[string]string)
	// 如果没有该method，直接返回nil
	root, ok := r.roots[method]
	if !ok {
		return nil, nil
	}
	// 从得到的node出发search
	n := root.search(searchParts, 0)
	if n != nil {
		parts := parsePattern(n.pattern)
		for index, part := range parts {
			if part[0] == ':' {
				params[part[1:]] = searchParts[index]
			}
			if part[0] == '*' && len(part) > 1 {
				params[part[1:]] = strings.Join(searchParts[index:], "/")
				break
			}
		}
		return  n, params
	}
	return nil, nil
}

func (r *router) handle(c *Context) {
	n, params := r.getRoute(c.Method, c.Path)
	if n != nil {
		c.Params = params
		key := c.Method + "-" + n.pattern
		r.handlers[key](c)
	} else {
		c.String(http.StatusNotFound, "404 NOT FOUND: %s\n", c.Path)
	}
}